package com.senlingspace.payment.douyin.service.impl;

import com.alibaba.fastjson2.JSON;
import com.senlingspace.common.core.domain.AjaxResult;
import com.senlingspace.common.core.redis.RedisLock;
import com.senlingspace.common.request.OrderRequest;
import com.senlingspace.framework.security.context.SecurityUtilExt;
import com.senlingspace.payment.core.ConcreteOrderProcess;
import com.senlingspace.payment.douyin.DouyinHttpClient;
import com.senlingspace.payment.douyin.bean.request.DouyinOrderRequest;
import com.senlingspace.payment.douyin.bean.request.DouyinShopQueryRequest;
import com.senlingspace.payment.douyin.bean.response.DouyinOrderResponse;
import com.senlingspace.payment.douyin.bean.response.DouyinShopQueryResponse;
import com.senlingspace.payment.douyin.service.DouYinOrderService;
import com.senlingspace.payment.douyin.service.DouYinShopService;
import com.senlingspace.payment.douyin.util.SignUtil;
import com.senlingspace.system.domain.SlkjShop;
import com.senlingspace.system.mapper.SlkjShopMapper;
import com.senlingspace.system.service.ISlkjShopService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import java.nio.charset.StandardCharsets;

@Slf4j
@Service
@AllArgsConstructor
public class DouYinOrderServiceImpl implements DouYinOrderService {

    private final RedisLock redisLock;
    private final DouYinShopService douYinShopService;
    private ISlkjShopService slkjShopService;
    SlkjShopMapper slkjShopMapper;
    private final ConcreteOrderProcess concreteOrderProcess;

    /**
     * 处理抖音创建订单（票类订单创建）
     *
     * @param douyinOrder
     * @return {@link AjaxResult }
     */
    public AjaxResult processOrderDouyin(DouyinOrderResponse.ResponseData.Order douyinOrder,String accountId) {
//      订单实收金额，即pay_amount+payment_discount
        Long receiptAmount = douyinOrder.getReceiptAmount();
        String poiIdString = douyinOrder.getPoiId();

        SlkjShop slkjShop = new SlkjShop();
        slkjShop.setDouyinPoiId(poiIdString);
        slkjShop.setAccountId(accountId);
        SlkjShop slkjShopRes = slkjShopMapper.selectSlkjShopByDouyin(slkjShop);
        if (slkjShopRes == null) {
            log.error("创建抖音类型订单时，查询抖音订单绑定的门店不存在，请先添加门店！");
            return AjaxResult.error("创建抖音类型订单时，查询抖音订单绑定的门店不存在，请先添加门店！");
        }

//        目前的订单只会查询到一个商品
        Integer num = 0;
        List<DouyinOrderResponse.ResponseData.Order.Product> products = douyinOrder.getProducts();
        for (DouyinOrderResponse.ResponseData.Order.Product product : products) {
            num = product.getNum();
        }
        //        productId是创建商品时自定义的id为 项目id,票价id
        String[] productIds = douyinOrder.getThirdSkuId().split(",");
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.setShopId(slkjShopRes.getShopId());
        orderRequest.setOpenId(douyinOrder.getOrderId());
        orderRequest.setProjectId(Long.valueOf(productIds[0]));
        ArrayList<OrderRequest.PayInventory> payInventorys = new ArrayList<>();
        OrderRequest.PayInventory payInventory = new OrderRequest.PayInventory();
        payInventory.setType("TICKET");
        payInventory.setQuantity(num);
        payInventory.setItemId(Long.valueOf(productIds[1]));
        payInventorys.add(payInventory);
        orderRequest.setPayInventories(payInventorys);
        String reqHash = DigestUtils.md5DigestAsHex(orderRequest.toString().getBytes(StandardCharsets.UTF_8));
        String lockKey = "DY_TICKET_ORDER_LOCK:" + reqHash;
        RLock lock = redisLock.getRLock(lockKey);

        boolean isLocked = false;
        try {
            isLocked = lock.tryLock(15, TimeUnit.SECONDS);
            if (isLocked) {
                return concreteOrderProcess.processOrderDouyin(orderRequest, douyinOrder.getOrderId(),receiptAmount);
            } else {
                log.warn("用户重复提交！锁超时：{}", lockKey);
                return AjaxResult.error("请勿重复下单！");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("抖音提交订单请求时发生异常：{}", e.getMessage(), e);
            return AjaxResult.error("下单记录失败，请刷新重试！");
        } finally {
            if (isLocked && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }


    }

    @Override
    public ArrayList<AjaxResult> createOrder(DouyinOrderRequest douyinOrderRequest) {

        log.info("抖音创建票类订单，入参：{}", JSON.toJSONString(douyinOrderRequest));
        ArrayList<AjaxResult> ajaxResults = new ArrayList<>();
        DouyinOrderResponse douyinOrderResponse = DouyinHttpClient.invoke(douyinOrderRequest);
        if (douyinOrderResponse.getData().getErrorCode() != 0) {
            log.error("创建票类订单时，调用抖音订单异常，请求参数：" + JSON.toJSONString(douyinOrderRequest));
            log.error("创建票类订单时，调用抖音订单异常，返回结果：" + JSON.toJSONString(douyinOrderResponse));
            AjaxResult error = AjaxResult.error("创建票类订单时，调用抖音订单异常，请求参数：" + douyinOrderRequest.toString());
            ajaxResults.add(error);
            return ajaxResults;
        }
        List<DouyinOrderResponse.ResponseData.Order> orders = douyinOrderResponse.getData().getOrders();

        for (int i = 0; i < orders.size(); i++) {
            DouyinOrderResponse.ResponseData.Order order = orders.get(i);
            AjaxResult ajaxResult = processOrderDouyin(order,douyinOrderRequest.getAccountId());
            ajaxResults.add(ajaxResult);
        }
        return ajaxResults;
    }


}
